package service

import (
	"InstantCommunication/modules"
	"InstantCommunication/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strconv"
	"time"
)

// GetUserList
// @Tags 用户模块
// @Summary 查询用户
// @Success 200 {string} json{"code","message"}
// @Router /user/getUserList [get]
func GetUserList(c *gin.Context) {
	data := make([]*modules.UserBasic, 10)
	data = modules.GetUserList()
	c.JSON(200, gin.H{
		"message": data,
	})
}

// FindUserByNameAndPassword
// @Tags 用户模块
// @Summary 用户登录
// @Param name query string false "用户名"
// @Param password query string false "密码"
// @Success 200 {string} json{"code","message"}
// @Router /user/findUserByNameAndPassword [post]
func FindUserByNameAndPassword(c *gin.Context) {
	name := c.Request.FormValue("name")
	password := c.Request.FormValue("password")
	user := modules.FindUserByName(name)
	if user.Name == "" {
		c.JSON(200, gin.H{
			"code":    -1,
			"message": "user name doesn't exist",
		})
		return
	}
	flag := utils.ValidPassword(password, user.Salt, user.Password)
	if !flag {
		c.JSON(200, gin.H{
			"code":    -1,
			"message": "password wrong",
		})
		return
	}
	password = utils.MakePassword(password, user.Salt)
	data := modules.FindUserByNameAndPassword(name, password)
	c.JSON(200, gin.H{
		"code":    0,
		"message": "login success",
		"data":    data,
	})
	return
}

// CreateUser
// @Tags 用户模块
// @Summary 新增用户
// @Param name query string false "用户名"
// @Param password query string false "密码"
// @Param correctPassword query string false "确认密码"
// @Success 200 {string} json{"code","message"}
// @Router /user/createUser [get]
func CreateUser(c *gin.Context) {
	user := modules.UserBasic{}
	user.Name = c.Request.FormValue("name")
	password := c.Request.FormValue("password")
	correctPassword := c.Request.FormValue("identity")
	fmt.Println(user.Name, password, correctPassword)

	salt := uuid.NewString()
	// salt := fmt.Sprintf("%08d", rand.Int31())

	loginTime := time.Now()
	time.Sleep(time.Second * 2)
	logoutTime := time.Now()
	user.LoginTime = loginTime
	user.LogoutTime = logoutTime
	user.HeartbeatTime = loginTime.Add(logoutTime.Sub(loginTime))

	if user.Name == "" || password == "" || correctPassword == "" {
		c.JSON(-1, gin.H{
			"code":    -1,
			"message": "username or password cannot be empty",
		})
		return
	}

	userNameCheck := modules.FindUserByName(user.Name)
	if userNameCheck.Name != "" {
		c.JSON(-1, gin.H{
			"code":    -1,
			"message": "user has been registered",
		})
		return
	}

	if password != correctPassword {
		c.JSON(-1, gin.H{
			"code":    -1,
			"message": "password wrong",
		})
		return
	}
	user.Password = utils.MakePassword(password, salt)
	user.Salt = salt
	modules.CreateUser(user)
	c.JSON(200, gin.H{
		"code":    0,
		"message": "create user success",
		"data":    user,
	})
}

// DeleteUser
// @Tags 用户模块
// @Summary 删除用户
// @Param id query string false "id"
// @Success 200 {string} json{"code","message"}
// @Router /user/deleteUser [get]
func DeleteUser(c *gin.Context) {
	user := modules.UserBasic{}
	id, _ := strconv.Atoi(c.Query("id"))
	user.ID = uint(id)
	modules.DeleteUser(user)
	c.JSON(200, gin.H{
		"code":    0,
		"message": "delete user success",
		"data":    user,
	})
}

// UpdateUser
// @Tags 用户模块
// @Summary 修改用户
// @Param id formData string false "id"
// @Param name formData string false "用户名"
// @Param password formData string false "密码"
// @Param phone formData string false "电话"
// @Param email formData string false "邮箱"
// @Success 200 {string} json{"code","message"}
// @Router /user/updateUser [post]
func UpdateUser(c *gin.Context) {
	user := modules.UserBasic{}
	err := c.ShouldBindJSON(&user)
	if err != nil {
		log.Println(err)
		c.JSON(-1, gin.H{
			"code":    -1,
			"message": "update user fail",
		})
		return
	} else {
		modules.UpdateUser(user)
		c.JSON(200, gin.H{
			"code":    0,
			"message": "update user success",
		})
	}

	//id, _ := strconv.Atoi(c.PostForm("id"))
	//user.ID = uint(id)
	//user.Name = c.PostForm("name")
	//user.PassWord = c.PostForm("password")
	//user.Phone = c.PostForm("phone")
	//user.Email = c.PostForm("email")

	//_, err = govalidator.ValidateStruct(user)
	//if err != nil {
	//	fmt.Println(err)
	//	c.JSON(-1, gin.H{
	//		"code": -1,
	//		"message": "update user fail",
	//	})
	//} else {
	//	modules.UpdateUser(user)
	//	c.JSON(200, gin.H{
	//		"code": 0,
	//		"message": "update user success",
	//	})
	//}
}

// 防止跨域站点伪造请求
var upGrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func SendMessage(c *gin.Context) {
	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Println(err)
		return
	}
	defer func(ws *websocket.Conn) {
		err := ws.Close()
		if err != nil {
			log.Println(err)
			return
		}
	}(ws)
	MessageHandler(ws, c)
}

func MessageHandler(ws *websocket.Conn, c *gin.Context) {
	for {
		message, err := utils.Subscribe(c, utils.PublishKey)
		if err != nil {
			fmt.Println(err)
		}
		tm := time.Now().Format("2006-01-02 15:04:05")
		m := fmt.Sprintf("[ws][%s]:%s", tm, message)
		err = ws.WriteMessage(websocket.TextMessage, []byte(m))
		if err != nil {
			log.Println(err)
		}
	}
}

func SendUserMessage(c *gin.Context) {
	modules.Chat(c.Writer, c.Request)
}

func SearchFriends(c *gin.Context) {
	id, _ := strconv.Atoi(c.Request.FormValue("userId"))
	users := modules.SearchFriend(uint(id))
	c.JSON(200, gin.H{
		"code":    0,
		"message": "Search Friends success",
		"data":    users,
	})
}
